---
title: React原理
authors: Hypoxia
date: 2025.4.29
---

### 宏观逻辑

1. react 更新都会有个触发对象即 fiber
2. react 更新都会获取 queue
3. react 更新都会生成一个更新任务即 update
4. react 更新都会生成一个优先级即 lane
5. react 更新都依次将 fiber、queue、update、lane 放入 concurrentQueues
6. react 有三种优先级：lane(更新优先级)、eventPriority(事件优先级)、schedulerPriority(调度优先级)
7. react 更新时会触发 processRootScheduleInMicrotask(调度任务)
8. processRootScheduleInMicrotask(调度任务) 会发起 scheduleCallback(微调度任务)

### 专业名词

1. fiberRoot: 应用根节点
   1. pendingUpdatersLaneMap: 根据优先级保存的待处理中的触发更新的 fiber 的映射
   2. memoizedUpdaters: 保存的触发更新的 fiber
2. fiber: React 节点对象
   1. updateQueue: 更新队列
      1. shared: 并发更新队列
3. hostRootFiber: fiber 根节点
4. update: 更新任务
5. concurrentQueues: 并发队列
6. workInProgressRoot: 工作中的 fiberRoot
7. workInProgressRootRenderLanes: 工作中的渲染优先级
8. newTask: 微调度任务
9. taskQueue: 任务调度队列；其是最小堆
10. lane: 车道模型
    | Lane 名称 | 优先级 | 用途或示例 |
    | ----------------------- | ------ | --------------------------------------- |
    | **SyncLane** | 最高（同步） | 用户交互（点击按钮）导致的同步更新 |
    | **InputContinuousLane** | 高 | 连续输入（拖动、滑动） |
    | **DefaultLane** | 中 | 普通的异步更新，如 `setState` |
    | **TransitionLane(s)** | 中低 | 使用 `startTransition()` 包裹的更新（非紧急 UI 更新） |
    | **IdleLane** | 最低 | 空闲时执行，如预加载、日志收集等 |
    | **OffscreenLane** | 特殊 | 用于隐藏组件、预渲染 |

### 数据结构

1. update
   ```js
   const update = {
     lane,
     tag,
     payload,
     callback,
     next,
   };
   ```
2. updateQueue
   ```js
   const updateQueue = {
     baseState,
     firstBaseUpdate,
     lastBaseUpdate,
     shared,
     effects: [],
   };
   ```
3. shared
   ```js
   const shared = {
      hiddenCallbacks,
      lanes,
      pending,
   },
   ```
4. concurrentQueues
   ```js
   concurrentQueues[concurrentQueuesIndex++] = fiber;
   concurrentQueues[concurrentQueuesIndex++] = queue;
   concurrentQueues[concurrentQueuesIndex++] = update;
   concurrentQueues[concurrentQueuesIndex++] = lane;
   ```
5. newTask
   ```js
   const newTask = {
     id,
     callback,
     priorityLevel,
     startTime,
     expirationTime,
     sortIndex,
   };
   ```
6. memoizedState
   ```js
   const initialState: RootState = {
     element,
     isDehydrated,
     cache,
   };
   ```

### React 首次渲染做了什么

#### createRoot

1. FiberRootNode: 创建 fiberRoot(应用根节点)
   1. this.containerInfo: 保存了容器 DOM
   2. this.pendingUpdatersLaneMap: 创建存放不同优先级下触发更新 fiber 的数据结构
2. createHostRootFiber: 创建 hostRootFiber(fiber 根节点)
3. fiberRoot.current 中保存 hostRootFiber; hostRootFiber.stateNode 中保存 fiberRoot
4. 初始化 hostRootFiber.memoizedState(保存的状态)
5. initializeUpdateQueue: 初始化更新队列
6. markContainerAsRoot: 在容器 DOM 上保存 fiberRoot
7. listenToAllSupportedEvents: 监听容器 DOM 下的事件

#### root.render

1. updateContainer
   1. 获取 hostRootFiber
   2. requestUpdateLane: 请求本次更新优先级
   3. updateContainerImpl
      1. getContextForSubtree: 获取触发更新 fiber 的 context(上下文)
      2. createUpdate: 创建 update(更新任务)
      3. 保存 reactElement，即将其保存至 update.payload
      4. enqueueUpdate: 传入 fiber、update 和 lane
         1. 获取 fiber.updateQueue.shared(并发更新队列)
         2. enqueueConcurrentClassUpdate
            1. enqueueUpdate: 以 fiber、queue、update、lane 顺序加入 concurrentQueues(并发队列)
            2. getRootForUpdatedFiber: 获取 fiber 的 fiberRoot
      5. scheduleUpdateOnFiber: 传入 fiberRoot、hostRootFiber 和 lane
         1. markRootUpdated: 将 lane 同步至 root.pendingLanes
         2. addFiberToLanesMap: 将 fiber 保存至对应 lanes 的映射中，即 root.pendingUpdatersLaneMap 中
         3. ensureRootIsScheduled:
            1. 将 fiberRoot 保存至 firstScheduledRoot 和 lastScheduledRoot 组成的链表中
            2. scheduleImmediateTask: 发起调度任务
2. processRootScheduleInMicrotask: 调度任务
   1. scheduleTaskForRootDuringMicrotask
      1. markStarvedLanesAsExpired: 给 所有 lanes 设置过期时间
      2. getNextLanes: 获取下次更新的 lanes(管道)
      3. 将 lanes 转成对应的 schedulerPriority(调度优先级)
      4. scheduleCallback: 发起微调度任务，传入 schedulerPriority(调度优先级)和 performWorkOnRootViaSchedulerTask
         1. 根据 schedulerPriority(调度优先级) 生成微调度任务过期时间
         2. 创建 newTask(微调度任务)，并在其 newTask.callback 保存 performWorkOnRootViaSchedulerTask
         3. 将 newTask(微调度任务)推入 taskQueue(微调度最小堆)
         4. requestHostCallback: 调用 schedulePerformWorkUntilDeadline
            1. schedulePerformWorkUntilDeadline: 请求执行 newTask(微调度任务)
3. performWorkUntilDeadline
   1. flushWork
      1. workLoop
         1. peek: 获取要执行的 newTask(微调度任务)
         2. performWorkOnRootViaSchedulerTask: 执行的 callback 回调
            1. getNextLanes: 获取下一次 lane(更新优先级)
            2. performWorkOnRoot
               1. renderRootSync: 执行同步渲染
                  1. movePendingFibersToMemoized: 根据 lanes(管道) 将 root.pendingUpdatersLaneMap 里的 fiber 添加到 root.memoizedUpdaters
                  2. prepareFreshStack: 预刷新堆栈;
                     1. createWorkInProgress
                        1. 创建新 hostRootFiber 作为 workInProgress, 大部分从 current 拷贝如 memoizedProps、memoizedState、updateQueue、child 等
                        2. workInProgress.alternate 保存 current(已渲染 fiber), current.alternate 保存 workInProgress(构建的 fiber)
                     2. 重置 fiberRoot 相关属性，并赋值给 workInProgressRoot
                     3. finishQueueingConcurrentUpdates: 处理 concurrentUpdates
                        1. 将 update 存放进对应 fiber 下的 queue.pending 环形链表中
                        2. markUpdateLaneFromFiberToRoot: 将 lane 递归向上合并 fiber.lanes(更新优先级)
                  3. workLoopSync: 循环执行 workInProgress(工作 fiber)
                     1. performUnitOfWork
                        1. runWithFiberInDEV->beginWork->updateHostRoot
                           1. pushHostRootContext: fiber 处理时处在什么 DOM 节点的上下文
                           2. cloneUpdateQueue: 对 current.updateQueue 进行浅拷贝
                           3. processUpdateQueue: 接收 workInProgress(构建 fiber)、props(更新的 props)、lanes()
                              1. 将 workInProgress.updateQueue.shared.pending 加入 workInProgress.updateQueue 链表中
                              2. 将组成的新链表加入 current.updateQueue 中
                              3. 循环执行新链表，并根据 lane 判断是否需要执行 update
                              4. getStateFromUpdate: 将 update 内容转换成 baseState(起点计算状态)
                                 1. baseState.element 保存了 update.payload.element
                              5. 将跳过的 update 组成的链表存贮在 updateQueue 中即 firstBaseUpdate 和 lastBaseUpdate 中
                              6. markSkippedUpdateLanes: 在 workInProgressRootSkippedLanes 同步被跳过的 lanes
                              7. 将最终的 baseState 赋值给 workInProgress.memoizedState(保存状态)
                           4. reconcileChildren->reconcileChildFibers->reconcileChildFibersImpl: 构建子 fiber
                              1. 根据 element.$$typeof 执行不同构建 fiber 逻辑
                                 1. reconcileSingleElement: 单个 element 构建
                                    1. createFiberFromElement->createFiberFromTypeAndProps
                                       1. createFiber: 根据 fiberTag, pendingProps 创建 fiber
                                       2. 赋值 fiber.type、fiber.elementType、和 fiber.lanes
                                       3. coerceRef: 赋值 ref
                                       4. created.return 保存 returnFiber
                                       5. placeSingleChild: 标记 newFiber.flags，表示提交时的操作类型
                        2. unitOfWork.memoizedProps 保存 unitOfWork.pendingProps
                        3. 将 next 赋值给 workInProgress，直至 next 为空结束
                        4. completeUnitOfWork
                           1. runWithFiberInDEV->completeWork
                              1. 根据 tag 不同选择不同构建 DOM 方式
                              2. createInstance: 创建 DOM 元素
                                 1. 根据 type 创建 DOM 元素
                                 2. precacheFiberNode: DOM[internalInstanceKey] 保存对应的 fiber
                                 3. updateFiberProps: DOM[internalPropsKey] 保存对应的 props
                              3. appendAllChildren: 创建的 DOM 插入 node.stateNode(子 fiber 下的 DOM 节点)
                              4. workInProgress.stateNode 中保存 instance(创建 DOM)
                              5. finalizeInitialChildren->setInitialProperties: 将 props 转换成 DOM 上的属性
                              6. bubbleProperties: 更新 childLanes(子树 lane 合集)
                           2. 向上循环直至 completedWork.return 为 null
                  4. 重置 workInProgressRoot(构建中的 fiberRoot) 和 workInProgressRootRenderLanes(构建中的 lanes)
                  5. finishQueueingConcurrentUpdates: 执行 concurrentUpdates(并发队列)
               2. finishConcurrentRender: 将构建的 fiber 进行提交操作
                  1. 更新 root.finishedWork(构建完成的 fiber 树) 和 root.finishedLanes(构建完成的 lanes)
                  2. commitRootWhenReady->commitRoot->commitRootImpl
                  3. markRootFinished:
